package cn.virens.common.mybatis.service.dubbo.provider;

import cn.virens.common.mybatis.entity.BaseModel;
import cn.virens.common.mybatis.entity.param.PageParam;
import cn.virens.common.mybatis.entity.result.PageResult;
import cn.virens.common.mybatis.entity.result.PageResultQuery;
import cn.virens.common.mybatis.mapper.AbstrMapper;
import cn.virens.common.mybatis.mapper.example.Example;
import cn.virens.common.mybatis.mapper.example.ExampleCriteria;
import cn.virens.common.mybatis.service.dubbo.BaseReadProvider;
import cn.virens.common.util.core.Assert;
import cn.virens.common.util.exception.APIException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 通用service实现类
 *
 * @param <M> DO层接口类型
 * @param <T> 实体类型
 * @author virens
 */
public abstract class BaseReadProviderImpl<M extends AbstrMapper<T>, T extends BaseModel> implements BaseReadProvider<T> {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected final Class<T> clazz;

    @Autowired
    protected M mBaseMapper;

    public BaseReadProviderImpl(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    @Transactional(readOnly = true)
    public List<? extends T> selectAll(Map<String, Object> param) {
        return mBaseMapper.selectByExample(Example.newInstance());
    }

    @Override
    @Transactional(readOnly = true)
    public T selectOne(Serializable id) throws APIException {
        return mBaseMapper.selectByPrimaryKey(id).orElse(null);
    }

    @Override
    @Transactional(readOnly = true)
    public PageResult<?> selectPage(PageParam param) throws APIException {
        return PageResultQuery.selectPage(param, w -> doPageQuery(w, param));
    }

    /**
     * 查询一条记录
     *
     * @param example 查询条件
     * @return 记录
     * @throws APIException 一般异常
     */
    protected T selectItem(Example example) throws APIException {
        return mBaseMapper.selectOneByExample(example);
    }

    /**
     * 默认查询全部，如需使用分页，并且有条件查询，复写该方法
     *
     * @param param 查询参数
     * @return 记录列表
     * @throws APIException 一般异常
     */
    protected List<?> doPageQuery(PageResultQuery query, PageParam param) throws APIException {
        return selectAll(query.params());
    }

    /**
     * 校验参数方式填充查询条件
     *
     * @param ec 条件构造器
     * @param c  条件
     * @param v  值
     * @return 条件构造器
     */
    protected ExampleCriteria fill0(ExampleCriteria ec, String c, Object v) {
        return ec.andCondition(c, Assert.isEmpty(v, "参数为空"));
    }

    /**
     * 普通参数方式填充查询条件
     *
     * @param ec 条件构造器
     * @param c  条件
     * @param v  值
     * @return 条件构造器
     */
    protected ExampleCriteria fill1(ExampleCriteria ec, String c, Object v) {
        return ec.andCondition(c, v);
    }
}
